/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

using Microsoft.VisualStudio.Modeling.Shell;

namespace DslEditorPowerToy.Controls.Languages.Designers
{
    /// <summary>
    /// Control that acts as container for a editor host
    /// </summary>
    public abstract partial class EditorHostContainerBase : UserControl, IEditorHostContainer
    {
        private EditorHostControl _editorHostControl = null;
        private ModelingDocView _docView = null;
        private ComponentSelectionBroker _selectionBroker = null;

        #region Constructors
        [CLSCompliant(false)]
        public EditorHostContainerBase(ModelingDocView docView, Assembly editorDeclaringAssembly)
        {
            this._docView = docView;
            if (null != this._docView)
                this._docView.DocData.DocumentLoaded += new EventHandler(_docData_DocumentLoaded);

            this._editorHostControl = new EditorHostControl(editorDeclaringAssembly);

            InitialiseControls();
        }

        #endregion

        #region IEditorHostContainer Members

        /// <summary>
        /// Gets the current editor
        /// </summary>
        public IHostedEditorDefinition CurrentEditor
        {
            get
            {
                return this._editorHostControl.CurrentEditor;
            }
        }
        /// <summary>
        /// Gets and sets the navigation style for the editors
        /// </summary>
        public NavigationOrientationStyle NavigationStyle
        {
            get
            {
                return this._editorHostControl.NavigationStyle;
            }
            set
            {
                this._editorHostControl.NavigationStyle = value;
            }
        }
        /// <summary>
        /// Activates specified editor
        /// </summary>
        public void ActivateEditor(Guid editorId)
        {
            this._editorHostControl.ActivateEditor(editorId);
        }
        /// <summary>
        /// Gets list of editors
        /// </summary>
        public List<IHostedEditorDefinition> Editors
        {
            get
            {
                return this._editorHostControl.GetEditors();
            }
        }        

        #endregion

        #region Protected Methods
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    if (null != this._editorHostControl)
                    {
                        this._editorHostControl.EditorChanged -= new EventHandler(editorHostControl_EditorChanged);
                        this._editorHostControl.Dispose();
                    }

                    if ((null != this._docView)
                        && (null != this._docView.DocData))
                    {
                        this._docView.DocData.DocumentLoaded -= _docData_DocumentLoaded;
                    }

                    if (null != this._selectionBroker)
                    {
                        this._selectionBroker.EnvironmentSelectionChanged -= _selectionBroker_EnvironmentSelectionChanged;
                        this._selectionBroker.Dispose();
                    }
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }
        /// <summary>
        /// Handles loading of control
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //Creates a selection broker
            this._selectionBroker = new ComponentSelectionBroker(this._docView, this._editorHostControl);
            this._selectionBroker.RegisterDocView(this._docView);
            this._selectionBroker.EnvironmentSelectionChanged += new SelectionChangedEventHandler(_selectionBroker_EnvironmentSelectionChanged);
        }

        /// <summary>
        /// Handles change in editor
        /// </summary>
        protected virtual void OnEditorChanged()
        {
            //Nothing to do yet here since we dont have any UI to update for active editor
        }
        /// <summary>
        /// Handles change in environment selection
        /// </summary>
        protected virtual void OnEnvironmentSelectionChanged(ISelectionProvider selectionProvider, SelectionChangeSource source)
        {
        }
        #endregion

        #region Control Handlers
        /// <summary>
        /// Handles changes in editor
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editorHostControl_EditorChanged(object sender, EventArgs e)
        {
            OnEditorChanged();
        }
        /// <summary>
        /// Handles changes of selection in VS environment
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _selectionBroker_EnvironmentSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            OnEnvironmentSelectionChanged(e.SelectionProvider, e.Source);
        }
        /// <summary>
        /// Handles when DocData is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _docData_DocumentLoaded(object sender, EventArgs e)
        {
            this._editorHostControl.CurrentDocData = this._docView.DocData;
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Initialise controls
        /// </summary>
        private void InitialiseControls()
        {
            this.SuspendLayout();

            //Add controls
            this._editorHostControl.Location = new Point(0, 0);
            this._editorHostControl.Dock = DockStyle.Fill;
            this._editorHostControl.EditorChanged += new EventHandler(editorHostControl_EditorChanged);
            this.Controls.Add(this._editorHostControl);

            this.ResumeLayout(false);
            this.PerformLayout();
        }
        #endregion
    }
}
